<!-- 文件上传组件 -->
<template>
  <van-field
    name="uploader"
    :required="required"
    :label="labelText"
    :rules="[{ required: required, message: message }]"
  >
    <template #input>
      <van-uploader
        :preview-size="previewSize"
        :accept="accept"
        :show-upload="!readonly"
        :multiple="false"
        :max-size="5000 * 1024"
        @oversize="onOversize"
        :max-count="maxCount"
        :deletable="!readonly"
        :before-read="beforeRead"
        :after-read="onRead"
        :before-delete="onDel"
        :upload-text="'最多' + maxCount + '张'"
        v-model="fileList"
      />
    </template>
  </van-field>
</template>

<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import { showToast } from 'vant'
import { upload_file, get_files } from '@/api/api.js'
import { compressFileByCanvas, base64ToFile } from '@/utils/file.js'
const emit = defineEmits(['update:modelValue', 'uploadSuccess'])

const props = defineProps({
  // label名称
  labelText: {
    type: String,
    default: '文件上传'
  },

  // 是否必填
  required: {
    type: Boolean,
    default: false
  },

  // 提示语
  message: {
    type: String,
    default: '请上传'
  },

  // 双向绑定的值
  modelValue: {
    type: String,
    default: ''
  },

  // 上传附件接受的类型
  accept: {
    require: false,
    default: 'image/*'
  },

  // readonly true 只读模式/禁用模式 false 表单模式
  readonly: {
    type: Boolean,
    default: false
  },

  // 上传文件最大数量值
  maxCount: {
    require: false,
    default: 10
  },
  previewSize: {
    require: false,
    default: '80px'
  }
})

watch(
  () => props.modelValue,
  val => {}
)

const fileList = ref([])
const fileType = ref('')
const headerImage = ref(null)

const onOversize = file => {
  console.log(file)
  showToast('文件大小不能超过 5M')
}
const beforeRead = file => {
  return new Promise((resolve, reject) => {
    if (file.type == 'image/jpeg') {
      // 这里可以进行前端图片压缩处理
      resolve(file)
    } else if (file.type == 'image/png') {
      // 这里可以进行前端图片压缩处理
      resolve(file)
    } else {
      showToast('请上传 jpg或png 格式图片')
      reject()
    }
  })
}

// 处理图片
const imgPreview = file => {
  // 看支持不支持FileReader
  if (!file || !window.FileReader) return
  if (/^image/.test(file.type)) {
    // 创建一个reader
    let reader = new FileReader()
    // 将图片2将转成 base64 格式
    reader.readAsDataURL(file)
    // 读取成功后的回调
    reader.onloadend = function () {
      let result = this.result
      let img = new Image()
      img.src = result
      if (this.result.length <= 500 * 1024) {
        headerImage.value = this.result
        let file2 = base64ToFile(headerImage.value, 'test.png')
        let data = new window.FormData()
        data.append('file', file2)
        fileList.value[fileList.value.length - 1].status = 'uploading'
        fileList.value[fileList.value.length - 1].message = '上传中...'
        upload_file(data).then(res => {
          if (res.succeed) {
            fileList.value[fileList.value.length - 1].status = 'done'
            fileList.value[fileList.value.length - 1].fileId = res.data
            let str = ''
            fileList.value.forEach(item => {
              str += item.fileId + ','
            })
            emit('update:modelValue', str)
            // 这里需要看上传成功后this.uploader是否有值
          } else {
            fileList.value[fileList.value.length - 1].status = 'failed'
            fileList.value[fileList.value.length - 1].message = '上传失败'
          }
        })
      } else {
        img.onload = function () {
          let data1 = compressFileByCanvas(img)
          headerImage.value = data1
          let file2 = base64ToFile(headerImage.value, 'test.png')
          let data = new window.FormData()
          data.append('file', file2)
          console.log(fileList.value)
          fileList.value[fileList.value.length - 1].status = 'uploading'
          fileList.value[fileList.value.length - 1].message = '上传中...'
          upload_file(data).then(res => {
            if (res.succeed) {
              emit('update:modelValue', res.data)
              fileList.value[fileList.value.length - 1].status = 'done'
              fileList.value[fileList.value.length - 1].fileId = res.data
              let str = ''
              fileList.value.forEach(item => {
                str += item.fileId + ','
              })
              emit('update:modelValue', str)
              // 这里需要看上传成功后this.uploader是否有值
            } else {
              fileList.value[fileList.value.length - 1].status = 'failed'
              fileList.value[fileList.value.length - 1].message = '上传失败'
            }
          })
        }
      }
    }
  }
}

const onRead = file => {
  fileType.value = file.file.name
  // 压缩图片
  imgPreview(file.file)
}

const onDel = (val, index) => {
  if (val.file) {
    fileList.value.splice(
      fileList.value.findIndex(item => item.file === val.file),
      1
    )
    let str = ''
    fileList.value.forEach(item => {
      str += item.fileId + ','
    })
    emit('update:modelValue', str)
  } else {
    fileList.value.splice(
      fileList.value.findIndex(item => item.fileId === val.fileId),
      1
    )
    let str = ''
    fileList.value.forEach(item => {
      str += item.fileId + ','
    })
    emit('update:modelValue', str)
  }
}

const loadFile = data => {
  let arr = data.split(',')
  arr.splice(arr.length - 1)
  console.log(arr)
  fileList.value = []
  for (let i = 0; i < arr.length; i++) {
    get_files(arr[i]).then(res => {
      if (res.succeed) {
        // 图片base64转url
        let img = 'data:image/jpeg;base64,' + res.data.dataBase64
        let imgurl = base64ToFile(img, 'test.png')
        let url =
          window.webkitURL.createObjectURL(imgurl) ||
          window.URL.createObjectURL(imgurl)
        // 创建图片地址
        fileList.value.push({
          fileId: res.data.id,
          url: url,
          isImage: true,
          File: imgurl,
          name: fileType.value,
          content: 'data:image/jpeg;base64,' + res.data.dataBase64,
          status: 'done'
        })
      }
    })
  }
  console.log(fileList.value)
}

onMounted(() => {
  console.log(props.modelValue)
  if (props.modelValue && props.modelValue.length > 0) {
    fileList.value.push({
      status: 'uploading',
      message: '加载中...'
    })
    loadFile(props.modelValue)
  }
})
</script>
<style lang="scss" scoped></style>
